//
//  CCVector3.h
//  ShadowMapping
//
//  Created by Daniel Corleone on 13/6/14.
//  Copyright (c) 2014年 iCloverStudio. All rights reserved.
//

#ifndef __ShadowMapping__CCVector3__
#define __ShadowMapping__CCVector3__

#include "PlatformFeatures.h"
#include "CCDataType.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename T>
class Vector2 {
public:
    typedef T value_type;
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T& reference;
    typedef const T& const_reference;
    
public:
    union {
        struct {
            value_type x, y;
        };
        struct {
            value_type X, Y;
        };
        value_type v[2];
    };
    
public:
    explicit Vector2();
    explicit Vector2(value_type _x, value_type _y);
    
    Vector2(const Vector2<value_type>& otherV);
    
public:
    
};

#include "CCVector2.cpp"

typedef Vector2<Int8> vector2b;
typedef Vector2<Int16> vector2s;
typedef Vector2<UInt16> Vector2us;
typedef Vector2<Int32> Vector2i;
typedef Vector2<UInt32> Vector2ui;
typedef Vector2<Int64> vector2l;
typedef Vector2<UInt64> vector2ul;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename T>
class Vector3
{
public:
    typedef T value_type;
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T& reference;
    typedef const T& const_reference;
    
public:
    union {
        struct {
            value_type x, y, z;
        };
        struct {
            value_type X, Y, Z;
        };
        value_type v[3];
    };
    
public:
    explicit Vector3();
    explicit Vector3(value_type _x, value_type _y, value_type _z);
    
    Vector3(const Vector3<value_type>& otherV);
    
public:
    CC_INLINE Real Length() const;
    CC_INLINE Vector3<value_type>& Normalize();
    
    CC_INLINE Real DotProduct(const Vector3<value_type>& other) const;
    CC_INLINE Vector3<value_type> CrossProduct(const Vector3<value_type>& other) const;
    CC_INLINE Boolean Equal(const Vector3<value_type>& other, Real epsilon = FLOAT_MIN);
    
    CC_INLINE Vector3<value_type> operator-() const;
    CC_INLINE Vector3<value_type> operator-(const Vector3<value_type>& other) const;
    CC_INLINE Vector3<value_type> operator+(const Vector3<value_type>& other) const;
    CC_INLINE Vector3<value_type>& operator-=(const Vector3<value_type>& other);
    CC_INLINE Vector3<value_type>& operator+=(const Vector3<value_type>& other);
    CC_INLINE Vector3<value_type> operator*(const Real scale) const;
    CC_INLINE Vector3<value_type> operator*(const Vector3<value_type>& other) const;
    CC_INLINE Vector3<value_type>& operator*=(const Real scale);
    CC_INLINE Vector3<value_type>& operator*=(const Vector3<value_type>& other);
    CC_INLINE Vector3<value_type> operator/(const Real scale) const;
    CC_INLINE Vector3<value_type>& operator/=(const Real scale);

    CC_INLINE Boolean operator==(const Vector3<value_type>& other) const;
    CC_INLINE Boolean operator!=(const Vector3<value_type>& other) const;
    
public:
    static void Normalize(Vector3& _otherV);
    static Real DotProduct(const Vector3& v1, const Vector3& v2);
    static Vector3<value_type> CrossProduct(const Vector3<value_type>& v1, const Vector3<value_type>& v2);
};

/// implement files.
#include "CCVector3.cpp"

/** template instances */
typedef Vector3<Int8>   Vector3b;
typedef Vector3<Int16>  Vector3s;
typedef Vector3<UInt16> Vector3us;
typedef Vector3<Int32>  Vector3i;
typedef Vector3<UInt32> Vector3ui;
typedef Vector3<Int64>  Vector3l;
typedef Vector3<UInt64> Vector3ul;
typedef Vector3<Real>   Vector3f;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename T>
class Vector4
{
public:
    typedef T value_type;
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T& reference;
    typedef const T& const_reference;
    
public:
    union {
        struct {
            value_type x, y, z, w;
        };
        struct {
            value_type X, Y, Z, W;
        };
        value_type v[4];
    };
    
public:
    explicit Vector4();
    explicit Vector4(value_type _x, value_type _y, value_type _z, value_type _w);
    
    Vector4(const Vector4<value_type>& other);
};

#include "CCVector4.cpp"

typedef Vector4<Int8>   Vector4b;
typedef Vector4<Int16>  Vector4s;
typedef Vector4<UInt16> Vector4us;
typedef Vector4<Int32>  Vector4i;
typedef Vector4<UInt32> Vector4ui;
typedef Vector4<Int64>  Vector4l;
typedef Vector4<UInt64> Vector4ul;
typedef Vector4<Real>   Vector4f;

#endif /* defined(__ShadowMapping__CCVector3__) */

